package com.youdianstar.app.ui

import android.Manifest
import android.app.Dialog
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Color
import android.location.Location
import android.os.Handler
import android.os.Looper
import android.provider.Settings
import android.util.Log
import android.view.*
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.app.ActivityCompat
import androidx.drawerlayout.widget.DrawerLayout
import androidx.lifecycle.Observer

import coil.load
import com.youdianstar.app.ui.account.LoginActivity
import com.youdianstar.app.R
import com.youdianstar.app.databinding.ActivityMainBinding
import com.youdianstar.app.ui.account.ProfileActivity
import com.youdianstar.app.entity.BranchInfo
import com.youdianstar.app.entity.OrderQuery
import com.youdianstar.app.BuildConfig
import com.youdianstar.app.entity.MerchantLink
import com.youdianstar.app.entity.OrderInfo
import com.youdianstar.app.entity.UserCenterResponse
import com.youdianstar.app.entity.VersionUpdate
import com.youdianstar.app.support.paymentActionIntent
import com.youdianstar.app.util.DataAppManager
import com.youdianstar.app.util.MapJumpUtil
import com.youdianstar.app.util.map.BrsClusterManager
import com.youdianstar.app.util.LatLngUtil
import com.youdianstar.app.util.AppDialogUtil
import com.youdianstar.app.util.map.BrsClusterManager.MapCameraChangeListener
import com.youdianstar.app.common.*
import com.youdianstar.app.common.base.BaseActivity
import com.youdianstar.app.common.entity.*
import com.youdianstar.app.common.ex.getViewColor
import com.youdianstar.app.common.ex.setThrottleListener
import com.youdianstar.app.common.network.BaseApiResultObserver
import com.youdianstar.app.common.util.LogUtil
import com.youdianstar.app.common.util.MathUtil
import com.youdianstar.app.common.util.StrUtil
import com.youdianstar.app.common.util.Tool
import com.youdianstar.app.common.util.ScreenUtil
import com.youdianstar.app.common.util.anim.ViewHelper
import com.youdianstar.app.common.util.LanguageUtils
import com.youdianstar.app.common.util.LanguageConfig
import com.youdianstar.app.common.auko.startActivity

import com.google.android.gms.location.*
import com.google.android.gms.maps.*
import com.google.android.gms.maps.model.*
import com.google.android.gms.tasks.Task
import com.google.firebase.messaging.FirebaseMessaging
import com.google.maps.android.clustering.Cluster
import com.google.maps.android.clustering.view.DefaultClusterRenderer

import com.safframework.eventbus.EventBus
import com.safframework.eventbus.UI
import com.gyf.immersionbar.ktx.immersionBar
import org.koin.androidx.viewmodel.ext.android.viewModel
import kotlin.math.abs


class MainActivity : BaseActivity<ActivityMainBinding, MainViewModel>() {
    val TAG: String = MainActivity::class.java.simpleName

    override fun layoutId(): Int = R.layout.activity_main

    override fun initVariableId(): Int = BR.viewModel

    override fun initViewModel(): MainViewModel {
        val model: MainViewModel by viewModel()
        return model
    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        processIntent(intent)
    }

    private fun processIntent(intent: Intent?) {
        //处理刷新页面的数据
        LogUtil.i("----refresh mainActivity")
    }
    private val mHandler = Handler(Looper.myLooper()!!)
    private var mapFragment: SupportMapFragment? = null
    private var mMap: GoogleMap? = null
    private var isMapReady = false
    private var isLocationReady = false

    private lateinit var fusedLocationClient: FusedLocationProviderClient
    private val zoomLevel = 16.0f
    private var currentLevel = 14.0F
    private var currentCameraPosition: CameraPosition? = null
    private var mClusterManager :BrsClusterManager<BranchInfo>? = null
    private var mBranchRenderer :BranchRenderer? = null
    //点击 网点
    private var oldMarker: Marker? = null
    private var branchList: MutableList<BranchInfo> = mutableListOf()
    
    // 地图移动防抖处理
    private var debounceRunnable: Runnable? = null
    private val DEBOUNCE_DELAY = 500L // 防抖延迟时间（毫秒）
    private var selectBranch :BranchInfo? =null
    
    // 记录上一次的 zoom 级别，用于区分移动和缩放
    private var lastZoomLevel: Float? = null
    
    // 标记是否是点击 marker 触发的相机移动（点击 marker 时不应该触发接口查询）
    private var isMarkerClickTriggered = false

    //用户数据
    private var user: UserInfo? = null
    //临时标识: 关闭侧边栏
    private var drawerCacheEvent = false
    //标识-地图初始化权限授权
    private var isInitPermission = false
    private var locationDialog: Dialog?=null
    private var touchIdDialog: Dialog?=null
    //标识-强制更新 0: 无更新,1: 软更新, 2:强更新
    private var isForceTag = 0
    private var versionDialog: Dialog?=null

    override fun initViewLayout() {
        super.initViewLayout()
        immersionBar {
            statusBarDarkFont(true)
            titleBarMarginTop(mBinding.mainBarInner)
        }
        //初始化布局状态
        setLayoutUI(0)
        
        // 确保附近网点文字显示
        try {
            val labelText = findViewById<android.widget.TextView>(R.id.label_text)
            labelText?.let {
                it.text = "附近网点"
                it.visibility = View.VISIBLE
                it.setTextColor(Color.parseColor("#FF000000"))
                it.textSize = 12f
            }
        } catch (e: Exception) {
            android.util.Log.e("MainActivity", "设置附近网点文字失败", e)
        }
        
        // 根据用户权限控制商户中心菜单的显示/隐藏
        updateMerchantMenuVisibility()
        
        //初始化地图 ->加载网点
        mapFragment = supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment?
        
        mapFragment?.getMapAsync(object : OnMapReadyCallback {
            override fun onMapReady(googleMap: GoogleMap) {
                mMap = googleMap
                googleMap.setPadding(0,0,0,16)
                googleMap.uiSettings.isMyLocationButtonEnabled = false
                googleMap.uiSettings.isCompassEnabled = false
                googleMap.uiSettings.isZoomControlsEnabled = false
                googleMap.uiSettings.isMapToolbarEnabled = false
                
                // 设置地图样式和语言
                try {
                    googleMap.setMapStyle(MapStyleOptions.loadRawResourceStyle(this@MainActivity, R.raw.map_style))
                    
                    // Google Maps会根据应用的语言设置自动显示对应语言的地图标签
                    // 当前应用语言设置已通过LanguageUtils处理，地图会自动使用越南文
                } catch (e: Exception) {
                    // 忽略样式设置异常
                }
                googleMap.setOnMapClickListener { latLng ->
                    //点击地图其他区域->隐藏网点卡片,设置大头针未选中
                    setLayoutUI(6)
                    //点击空白处,收起租借中订单菜单
                    updateRentingMenu(false)
                    closeMapMarker()
                }
                //初始化坐标簇控制 对象
                mClusterManager = BrsClusterManager<BranchInfo>(this@MainActivity, googleMap)
                mClusterManager?.listener = object : MapCameraChangeListener{
                    override fun onCameraIdle() {
                        currentCameraPosition = mMap?.cameraPosition
                        val currentZoom = currentCameraPosition?.zoom ?: zoomLevel
                        currentLevel = currentZoom
                        
                        // 通过比较 zoom 级别来判断是移动还是缩放
                        // 如果 zoom 级别没变，说明是移动（pan）
                        // 如果 zoom 级别变了，说明是缩放（zoom）
                        val isPan = if (lastZoomLevel != null) {
                            // zoom 级别相同或非常接近（考虑浮点数精度），认为是移动
                            Math.abs(currentZoom - lastZoomLevel!!) < 0.01f
                        } else {
                            // 第一次，认为是移动（需要初始化查询）
                            true
                        }
                        
                        // 更新上一次的 zoom 级别
                        lastZoomLevel = currentZoom
                        
                        // 如果是点击 marker 触发的相机移动，不触发接口查询
                        if (isMarkerClickTriggered) {
                            android.util.Log.d("MainActivity", "检测到点击 marker 触发的相机移动，不触发查询")
                            return
                        }
                        
                        // 只有移动时才触发接口查询
                        if (isPan) {
                            android.util.Log.d("MainActivity", "检测到地图移动（zoom=${currentZoom}），触发查询")
                            onMapCameraIdle()
                        } else {
                            android.util.Log.d("MainActivity", "检测到地图缩放（zoom: $lastZoomLevel -> $currentZoom），不触发查询")
                        }
                    }
                }
                mBranchRenderer = BranchRenderer(this@MainActivity, googleMap, mClusterManager!!)
                mClusterManager?.renderer = mBranchRenderer
                mClusterManager?.setAnimation(true)
                //设置坐标簇监听
                mClusterManager?.setOnClusterItemClickListener { item ->
                    //点击大头针,显示网点卡片,只有地图显示的时候
                    // 标记这是点击触发的，避免触发接口查询
                    isMarkerClickTriggered = true
                    setLayoutUI(5)
                    showMapMarker(item)
                    // 延迟重置标志，确保 onCameraIdle 能检测到
                    mHandler.postDelayed({
                        isMarkerClickTriggered = false
                    }, 1000)
                    // 返回 true 阻止默认行为（包括移动地图到 marker 位置）
                    true
                }
                googleMap.setOnCameraIdleListener(mClusterManager)
                // 设置 marker 点击监听，返回 true 阻止默认行为（移动地图）
                googleMap.setOnMarkerClickListener { marker ->
                    // 让 ClusterManager 处理点击事件
                    mClusterManager?.onMarkerClick(marker) ?: false
                }
                mMap = googleMap
                isMapReady = true
                
                //设置地图 监听事件
                if (isLocationReady) {
                    setMapReady()
                }
                
                //更新地图 - 使用用户当前位置或本地保存的位置
                val savedLatLng = DataAppManager.instance.getLocalLatLng()
                // 初始化上一次 zoom 级别
                lastZoomLevel = zoomLevel
                updateMapLayout(savedLatLng)
                
                // 临时添加测试点位用于调试（后续会移除，实际点位来自接口）
                // addTestMarker(defaultLatLng)
            }
        })
    }

    override fun initData() {
        super.initData()
        EventBus.register(this.javaClass.simpleName, UI, BusEntity::class.java) {
            try {
                when (it.code) {
                    DataCode.CLOSE_DRAWER -> {
                        drawerCacheEvent = true
                        //mViewModel.closeDrawerEvent.value = false
                    }
                    DataCode.TOKEN_OUT -> {
                        DataAppManager.instance.clearUserWithCookies()
                        startActivity<LoginActivity>()
                    }
                    DataCode.ORDER_FINISH -> {
                        //轮询订单 - 已注释
                        // mViewModel.countOrderRequest()
                    }
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
        processIntent(intent)
        isInitPermission = false
        fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
        initLocationPermission()
        
        // 启动时自动获取用户信息
        if (DataAppManager.instance.isTokenExist()) {
            mViewModel.getAccount(false) // 不显示loading
        }

    }

    //初始化推送
    private fun initFirebasePush() {
        if (!DataAppManager.instance.firebaseReady) {
            FirebaseMessaging.getInstance().subscribeToTopic(Topic.TOPIC_GLOBAL)
            val token = DataAppManager.instance.getToken()
            FirebaseMessaging.getInstance().subscribeToTopic(Topic.TOPIC_TOKEN + token)
                .addOnCompleteListener {
                    if (it.isSuccessful) {
                        DataAppManager.instance.firebaseReady = true
                    }
                }
            FirebaseMessaging.getInstance().token.addOnCompleteListener { task ->
                if (!task.isSuccessful) {
                    LogUtil.d("FirebaseInstanceId", "getInstanceId failed:" + task.exception)
                    return@addOnCompleteListener
                }
                val tokenPush = task.result
                Log.d("FirebaseInstanceId", "token= $tokenPush")
            }
        }
    }


    /**
     * 强更新版本
     * --优先级比较高,但考虑网络延时,如果已经有弹框,先不显示
     * @param forceUpdate 是否强制更新
     */
    private fun showForceUpdateNotify(forceUpdate:Boolean){
        if (locationDialog?.isShowing == true || touchIdDialog?.isShowing == true)
            return
        versionDialog?.dismiss()
        versionDialog = AppDialogUtil.instance.showVersionUpdateDialog(this,
            title = getString(R.string.update_title),
            msg = getString(R.string.update_text),
            left = getString(R.string.Set_notNow), right = getString(R.string.Public_update),
            rightAction = {
                Tool.startStoreNow(this@MainActivity)
            }, forceUpdate)
        isForceTag = 0
    }

    /*开启指纹提示*/
    private fun showTouchIdNotify(){
        if (!DataAppManager.instance.isShowTouchId()){
            if (locationDialog?.isShowing == true)
                return
            touchIdDialog?.dismiss()
            touchIdDialog = AppDialogUtil.instance.showNotifyDialog(this,
                title = getString(R.string.Set_bio_title), msg = getString(R.string.Set_bio_content),
                leftAction =  {
                    startActivity<SettingActivity>()
                }, left = getString(R.string.Set_setUp),
                rightAction = {

                }, right = getString(R.string.Set_notNow))
            DataAppManager.instance.updateShowTouchId(1)
        }
    }

    /**
     * 处理初始化内容与Scheme事件
     * --优先级: 初始化权限提示>强制更新>Scheme事件(店主入住)>定位开关提示>指纹提示
     */
    private fun checkSchemeBisAction(){
        if (!isInitPermission)
            return //授权判断后 才进行下一步
        if (isForceTag>0)
            showForceUpdateNotify(isForceTag != 1)
        else
            // 版本检查已屏蔽
            // mViewModel.checkVersionUpdate(BuildConfig.VER_NAME)
        if (!DataAppManager.instance.isRequestConfig){
            // 系统配置接口已屏蔽
            // mViewModel.getSystemConfig()
            mViewModel.getAccount(false)
        }
        if (!StrUtil.isEmpty(DataAppManager.instance.partnerLinkId)){
            mViewModel.linkMerchantAccount(DataAppManager.instance.partnerLinkId)
        }else{
            // 生物验证弹窗已关闭，默认不使用生物验证
            // showTouchIdNotify()
        }
        //判断是否有邀请链接
        if (!StrUtil.isEmpty(DataAppManager.instance.friendLinkID)){
            val userCode = user?.inviteCode?:""
            if (DataAppManager.instance.friendLinkID == userCode){
                toastShow(getString(R.string.Rewards_error_inviteYourself))
                DataAppManager.instance.friendLinkID = ""
                return
            }
            mViewModel.redeemInvitationCode(DataAppManager.instance.friendLinkID)
        }
        //判断是否有奖励扫码
        if (!StrUtil.isEmpty(DataAppManager.instance.rewardCodeTx)){
            val type = DataAppManager.instance.rewardTypeTx
            mViewModel.redeemRewardCode(type,DataAppManager.instance.rewardCodeTx)
        }
    }

    override fun onResume() {
        super.onResume()
        user = DataAppManager.instance.getUser()
        checkSchemeBisAction()
        user?.let {
            setUserLayout(it)
            initFirebasePush()
            //检测刷新用户数据标签
            if (DataAppManager.instance.userUpdateTag){
                DataAppManager.instance.userUpdateTag = false
                mViewModel.getAccount(true) //重新获取用户信息(更新侧边栏数据)
            }
            if (DataAppManager.instance.rentEndTag){
                DataAppManager.instance.rentEndTag = false
                setLayoutUI(3) //订单 支付完了
            }
            //轮询订单 - 已注释
            // mViewModel.countOrderRequest()
        }
        if (drawerCacheEvent){
            mBinding.mainDrawerLayout.closeDrawer(mBinding.rlNavContent)
            drawerCacheEvent = false
        }
    }

    override fun onPause() {
        super.onPause()
        mViewModel.countJob?.cancel()
        mViewModel.requestJob?.cancel()
        rentUIState = 0
        if (mBinding.lottieCharging.isAnimating){
            mBinding.lottieCharging.pauseAnimation()
        }
    }

    override fun initLiveObserver() {
        super.initLiveObserver()
        mViewModel.closeDrawerEvent.observe(this, Observer {
            mBinding.mainDrawerLayout.closeDrawer(mBinding.rlNavContent)
        })

        //强制更新版本 - 已屏蔽
        /*
        mViewModel.versionUpdateLiveData.observe(this, object : BaseApiResultObserver<VersionUpdate>(false) {
            override fun onDataResult(data: VersionUpdate?) {
                super.onDataResult(data)
                data?.let { version ->
                    if (version.iteration){
                        isForceTag = if (version.forced) 2 else 1
                        if (isInitPermission)
                            showForceUpdateNotify(version.forced)//完成授权后才提示
                    }
                }
            }
        })
        */

        //系统配置接口 - 已屏蔽
        /*
        mViewModel.configResultLiveData.observe(this, object : BaseApiResultObserver<List<ConfigItem>>() {
            override fun onDataResult(data: List<ConfigItem>?) {
                super.onDataResult(data)
                data?.let {
                    DataAppManager.instance.isRequestConfig = true
                    DataAppManager.instance.saveConfig(it)
                    DataAppManager.instance.getLocalLatLng().let { local ->
                        setLayoutUI(6)//更新网点列表--隐藏当前选中网点
                        mMap?.clear()
                        updateMapLayout(local)
                    }
                }
            }
        })
        */

        mViewModel.userCenterResultLiveData.observe(this, object : BaseApiResultObserver<UserCenterResponse>(false) {
            override fun onDataResult(data: UserCenterResponse?) {
                super.onDataResult(data)
                dismissDialog()
                data?.let { userCenterResponse ->
                    val netUser = userCenterResponse.user // 从UserCenterResponse中提取user信息
                    DataAppManager.instance.getUser()?.let { local ->
                        local.code = netUser.id
                        local.phone = netUser.mobile
                        local.email = netUser.email
                        local.icon = netUser.avatar
                        local.nickname = netUser.nickName
                        local.birthday = netUser.birthday
                        local.sex = netUser.sex
                        local.google = false // UserCenterInfo没有google字段，使用默认值
                        local.isBranch = false // UserCenterInfo没有isBranch字段，使用默认值
                        DataAppManager.instance.saveCacheUser()
                        setUserLayout(local) //更新侧边栏数据
                    }
                }
            }
        })
        //商家入住关联
        mViewModel.merchantLinkLiveData.observe(this, object : BaseApiResultObserver<MerchantLink>(true) {
            override fun onDataResult(data: MerchantLink?) {
                super.onDataResult(data)
                DataAppManager.instance.partnerLinkId = ""
                mHandler.postDelayed({
                    dismissDialog()
                    toastShow(getString(R.string.home_LinkBrandSuccess))
                    mViewModel.getAccount(false) //重新获取用户信息(更新侧边栏数据)
                },2000L)
                //关联结束后-判断指纹（已关闭，默认不使用生物验证）
                // showTouchIdNotify()
            }

            override fun onNetError(code: Int, e: String?) {
                super.onNetError(code, e)
                DataAppManager.instance.partnerLinkId = ""
                dismissDialog()
                toastShow(e)
                //关联结束后-判断指纹（已关闭，默认不使用生物验证）
                // showTouchIdNotify()
            }
        })
        //邀请好友 邀请码处理
        mViewModel.redeemInviteResultData.observe(this, object : BaseApiResultObserver<Any>(true) {
            override fun onDataResult(data: Any?) {
                super.onDataResult(data)
                DataAppManager.instance.friendLinkID = ""
            }

            override fun onNetError(code: Int, e: String?) {
                super.onNetError(code, e)
                toastShow(e)
                DataAppManager.instance.friendLinkID = ""
            }
        })

        //奖励扫码兑换
        mViewModel.redeemRewardResultData.observe(this, object : BaseApiResultObserver<Any>(true) {
            override fun onDataResult(data: Any?) {
                super.onDataResult(data)
                when(DataAppManager.instance.rewardTypeTx){
                    "1" -> {
                        toastShow(getString(R.string.charge_couponTips))
                    }
                    "2" -> {
                        toastShow(getString(R.string.charge_promoTips))
                    }
                    else -> {
                        toastShow(getString(R.string.charge_cardTips))
                    }
                }
                DataAppManager.instance.rewardTypeTx = ""
                DataAppManager.instance.rewardCodeTx = ""
            }

            override fun onNetError(code: Int, e: String?) {
                super.onNetError(code, e)
                toastShow(e)
                DataAppManager.instance.rewardTypeTx = ""
                DataAppManager.instance.rewardCodeTx = ""
            }
        })

        /*网点数据刷新*/
        mViewModel.branchListResultData.observe(this, object : BaseApiResultObserver<List<Any>>(true) {
                override fun onDataResult(data: List<Any>?) {
                    super.onDataResult(data)
                    data?.let {
                        setLayoutUI(6)//更新网点列表--隐藏当前选中网点
                        refreshCluster(it)
                    }
                }
            })

        /*订单轮询*/
        mViewModel.queryResultData.observe(this, object : BaseApiResultObserver<OrderQuery>(false) {
            override fun onDataResult(data: OrderQuery?) {
                super.onDataResult(data)
                mViewModel.isRentingQuest = false
                data?.let { it ->
                    if (it.rent.isEmpty()) {
                        mViewModel.requestJob?.cancel()
                        mViewModel.countJob?.cancel()
                        if (it.unpaid.isNotEmpty()) {
                            mViewModel.orderDataFiled.set(it.unpaid[0])
                            setRentingLayout(4)//待支付订单-重置数据
                            setLayoutUI(2)//有待支付订单
                        } else {
                            if (it.surveying.isNotEmpty()){
                                mViewModel.orderDataFiled.set(it.surveying[0])
                                setRentingLayout(5)//调查中订单-重置数据
                                setLayoutUI(4)//有调查中订单
                            }else{
                                mViewModel.orderDataFiled.set(null)
                                setLayoutUI(3)//无租借中订单+无待支付订单+无调查中订单->隐藏订单
                            }
                        }
                    } else {
                        //有租借中订单
                        it.rent[0].let { orderInfo ->
                            when (orderInfo.state) {
                                DataCode.STATE_RENTING -> {
                                    //有租借中的订单
                                    mViewModel.orderDataFiled.set(orderInfo)
                                    mViewModel.distanceTime = abs(orderInfo.getRentingNow() - orderInfo.createTime)
                                    mViewModel.countOrderTime()
                                    if (isShowRentHelp){
                                        setRentingLayout(3,orderInfo) //更新订单布局
                                    } else{
                                        setRentingLayout(if (rentUIState == 0) 1 else 2,orderInfo)//更新订单布局
                                    }
                                    setLayoutUI(1)//有租借中订单
                                }
                                else -> {
                                    mViewModel.orderDataFiled.set(null)
                                    setLayoutUI(3)//异常情况 不显示订单
                                }
                            }
                        }
                    }
                }
            }

            override fun onNetError(code: Int, e: String?) {
                super.onNetError(code, e)
                mViewModel.isRentingQuest = false
                //toastShow(e)
            }
        })

    }

    override fun initClickEvent() {
        mBinding.mainDrawerLayout.addDrawerListener(object : DrawerLayout.DrawerListener {
            override fun onDrawerSlide(drawerView: View, slideOffset: Float) {
                val scale = 1 - slideOffset
                val rightScale = 0.8f + scale * 0.2f
                if (drawerView.tag == "LEFT"){
                    val leftScale = 1 - 0.3f * scale
                    mBinding.vBelow.visibility = if (slideOffset == 0.0f) View.GONE else View.VISIBLE
                    mBinding.vOffset.visibility = if (slideOffset == 0.0f) View.GONE else View.VISIBLE

                    mBinding.cardContainer.radius = ScreenUtil.dp2px(this@MainActivity,20f)*slideOffset
                    val layoutParams = ConstraintLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
                    layoutParams.setMargins(ScreenUtil.dp2px(this@MainActivity,25f*slideOffset).toInt(), 0, 0, 6*(if (slideOffset>0) 1 else 0))
                    mBinding.cardContainer.layoutParams = layoutParams
                    mBinding.rlNavContent.run {
                        ViewHelper.setScaleX(this, leftScale)
                        ViewHelper.setScaleY(this, leftScale)
                        ViewHelper.setAlpha(this, 0.6f + 0.4f * (1 - scale))
                        ViewHelper.setTranslationX(
                            mBinding.frContainer,
                            this.measuredWidth * (1 - scale)
                        )
                    }

                    mBinding.cardContainer.run {
                        ViewHelper.setPivotX(this, 0f)
                        ViewHelper.setPivotY(this, (this.measuredHeight / 2).toFloat())
                        this.invalidate()
                        ViewHelper.setScaleX(mBinding.frContainer, rightScale)
                        ViewHelper.setScaleY(mBinding.frContainer, rightScale)
                    }
                }
            }

            override fun onDrawerOpened(drawerView: View) {
                mBinding.mainDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
            }

            override fun onDrawerClosed(drawerView: View) {
                mBinding.mainDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
            }

            override fun onDrawerStateChanged(newState: Int) {}
        })

        mBinding.mainTopNav.setThrottleListener {
            //侧边栏--展开
            mBinding.mainDrawerLayout.openDrawer(mBinding.rlNavContent)
            mBinding.mainDrawerLayout.setScrimColor(Color.TRANSPARENT)
        }

        mBinding.ilMenu.ivAvatar.setThrottleListener {
            //侧边栏--头像
            startActivity<ProfileActivity>()
        }

        mBinding.ilMenu.drawerBtnVersion.setThrottleListener {
            //侧边栏--版本
        }

        mBinding.mainRlScan.setThrottleListener {
            //底部点击扫码
            if (!DataAppManager.instance.isTokenExist())
                return@setThrottleListener
            startActivity<ScanActivity>(Extra.IT_TYPE to BisType.Scan_Rent)
            //mViewModel.checkRentOrNot() 租借条件改扫码页面处理
        }

        mBinding.mainTopSearch.setThrottleListener {
            //跳转网点搜素列表
            startActivity<PlaceSearchActivity>()
        }

        mBinding.mapMerchant.setThrottleListener {
            //跳转网点列表--附近网点列表
            if (null==currentCameraPosition || currentCameraPosition?.target ==null){
                DataAppManager.instance.getDefaultLatLng().let { df ->
                    startActivity<BranchListActivity>(
                        Extra.IT_LAT to df.latitude,
                        Extra.IT_LNG to df.longitude
                    )
                }
            }else{
                currentCameraPosition?.target?.let { cameraP ->
                    startActivity<BranchListActivity>(
                        Extra.IT_LAT to cameraP.latitude,
                        Extra.IT_LNG to cameraP.longitude
                    )
                }
            }
        }

        mBinding.mapLocation.setThrottleListener {
            //更新地图定位
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED ) {
                initLocationPermission()
            }else{
                getMapLocation()
            }
            //点击地图其他按钮,收起租借中订单菜单
            updateRentingMenu(false)
        }

        // 地图放大按钮
        mBinding.mapZoomIn.setThrottleListener {
            val currentZoom = mMap?.cameraPosition?.zoom ?: zoomLevel
            val newZoom = currentZoom + 1f
            mMap?.animateCamera(CameraUpdateFactory.zoomTo(newZoom), 300, null)
            updateRentingMenu(false)
        }

        // 地图缩小按钮
        mBinding.mapZoomOut.setThrottleListener {
            val currentZoom = mMap?.cameraPosition?.zoom ?: zoomLevel
            val newZoom = currentZoom - 1f
            mMap?.animateCamera(CameraUpdateFactory.zoomTo(newZoom), 300, null)
            updateRentingMenu(false)
        }

        mBinding.clMerchantContainer.setThrottleListener {
            //网点布局--点击
            selectBranch?.let {
                startActivity<BranchDetailActivity>(
                    Extra.IT_ID to it.id,
                    Extra.IT_DISTANCE to it.distance
                )
            }
        }

        mBinding.clMainUnpaid.setThrottleListener {
            //待支付/调查中订单--点击布局
            mViewModel.orderDataFiled.get()?.let { data->
                if (data.state == DataCode.STATE_PROCESS){
                    startActivity<OrderDetailActivity>(Extra.IT_ORDERNO to data.orderNo)
                }else{
                    if (data.lost){
                        paymentActionIntent(this@MainActivity,BisType.Bis_Loss, amount = data.money, orderNo = data.orderNo, orderInfo = data)
                    }else{
                        paymentActionIntent(this@MainActivity,BisType.Bis_Rent, amount = data.money, orderNo = data.orderNo, orderInfo = data)
                    }
                }
            }
        }

        mBinding.clOrderRenting.setThrottleListener {
            //租借中订单--点击租借中计时
            mViewModel.orderDataFiled.get()?.let { data->
                startActivity<OrderDetailActivity>(Extra.IT_ORDERNO to data.orderNo)
            }
        }

        mBinding.clOrderInfo.setThrottleListener {
            //租借中订单--点击订单信息, 展开/隐藏 帮助布局
            updateRentingMenu()
        }

    }

    /**
     * 设置用户布局
     * @param userInfo user data
     */
    private fun setUserLayout(userInfo: UserInfo) {
        val formatUid = StrUtil.format8LenStr(userInfo.uid)
        
        // 设置用户昵称
        val nickname = if (!StrUtil.isEmpty(userInfo.nickname)) {
            userInfo.nickname
        } else {
            // 如果昵称为空，使用手机号后4位作为默认昵称
            if (!StrUtil.isEmpty(userInfo.phone) && userInfo.phone!!.length >= 4) {
                getString(R.string.user_default_prefix) + userInfo.phone!!.substring(userInfo.phone!!.length - 4)
            } else {
                getString(R.string.user_default_prefix)
            }
        }
        mBinding.ilMenu.tvNickname.text = nickname
        
        // 设置UID
        mBinding.ilMenu.tvName.text = if (userInfo.uid==0) "" else "U$formatUid"
        
        // 使用统一的商户权限检查逻辑
        val hasPermission = DataAppManager.instance.hasMerchantPermission()
        mBinding.ilMenu.menuMerchants.visibility = if (hasPermission) View.VISIBLE else View.GONE
        
        // 日志输出
        LogUtil.d("MerchantPermission", "setUserLayout: 商户权限检查结果: $hasPermission, 菜单显示状态: ${if (hasPermission) "显示" else "隐藏"}")
    }


    /**
     * 控制UI布局-大布局
     *
     * 1:租借中订单 2:待支付订单 3:无订单 4:调查中订单 5:选中网点 6:无网点
     */
    private fun setLayoutUI(state: Int) {
        when(state){
            1->{
                //租借中订单--显示订单布局
                mBinding.clMainRenting.visibility = View.VISIBLE
                mBinding.lottieCharging.playAnimation()
                mBinding.clMainUnpaid.visibility = View.GONE
                mBinding.mainClBottom.visibility = View.INVISIBLE
            }
            2->{
                //待支付订单--且地图收缩
                mBinding.clMainRenting.visibility = View.GONE
                mBinding.lottieCharging.pauseAnimation()
                mBinding.clMainUnpaid.visibility = View.VISIBLE
                mBinding.tvUnpaid.text = getString(R.string.home_unpaidOrder)
                mBinding.mainClBottom.visibility = View.INVISIBLE
            }
            3->{
                //无订单
                mBinding.clMainRenting.visibility = View.GONE
                mBinding.lottieCharging.cancelAnimation()
                mBinding.clMainUnpaid.visibility = View.GONE
                mBinding.mainClBottom.visibility = View.VISIBLE
            }
            4->{
                //调查中订单
                mBinding.clMainRenting.visibility = View.GONE
                mBinding.lottieCharging.cancelAnimation()
                mBinding.clMainUnpaid.visibility = View.VISIBLE
                mBinding.tvUnpaid.text = getString(R.string.home_underInvestigation)
                mBinding.mainClBottom.visibility = View.INVISIBLE
            }
            5 -> {
                mBinding.clMerchantContainer.visibility = View.VISIBLE
            }
            6 -> {
                mBinding.clMerchantContainer.visibility = View.GONE
            }
            else ->{
                mBinding.clMainRenting.visibility = View.GONE
                mBinding.clMainUnpaid.visibility = View.GONE
                mBinding.clMerchantContainer.visibility = View.GONE
                mBinding.mainClBottom.visibility = View.VISIBLE
                mBinding.ilMenu.drawerBtnVersion.text = "V " + BuildConfig.VER_NAME
                if (mBinding.lottieCharging.isAnimating){
                    mBinding.lottieCharging.cancelAnimation()
                }
                mBinding.lottieCharging.setAnimation(R.raw.charging_lottlie)
            }
        }
    }

    /***********************************订单部分********开始**************************/

    private var isShowRentHelp = false //标识帮助列表--隐藏/展示
    private var rentUIState = 0 //记录UI状态 用于订单更新时设置状态

    /**
     * 设置订单数据
     *
     * @param toState 目标状态
     *  1:初始时间  2.只显示时间,收起帮助列表 3:展示帮助列表 并旋转箭头 4:待支付订单置空数据 5:调查中订单
     */
    private fun setRentingLayout(toState: Int, info : OrderInfo? = null) {
        if (toState == 4 ||toState == 5) {
            //待支付/调查中订单--置空租借中数据
            mBinding.txPbId.text = String.format(getString(R.string.home_powerbankTx),"")
            mViewModel.orderTimeFiled.set("")
            mBinding.txPrice.text = String.format(getString(R.string.home_estimatedFeesTx),"")
        } else {
            if (toState==1){
                mViewModel.orderTimeFiled.set("")
            }
            info?.let { order ->
                mBinding.txPbId.text = String.format(getString(R.string.home_powerbankTx), order.pbNoTx())
                val symbolStr = DataAppManager.instance.symbolTx()
                mBinding.txPrice.text = String.format(getString(R.string.home_estimatedFeesTx),symbolStr+MathUtil.round(order.orderAmountValue()))
            }
        }
        isShowRentHelp = toState == 3
        rentUIState = toState

        //更改 订单帮助相关状态UI
        mBinding.ivHelpList.rotation = if (toState == 3) 90F else 0F
        mBinding.orderHelpLine.visibility = if (toState == 3) View.VISIBLE else View.GONE
        mBinding.clHelpRent.visibility = if (toState == 3) View.VISIBLE else View.GONE
        mBinding.clHelpReturn.visibility = if (toState == 3) View.VISIBLE else View.GONE
        mBinding.clHelpFault.visibility = if (toState == 3) View.VISIBLE else View.GONE
        mBinding.clHelpLost.visibility = if (toState == 3) View.VISIBLE else View.GONE
        mBinding.clHelpFAQ.visibility = if (toState == 3) View.VISIBLE else View.GONE
    }

    /**
     * 更新租借中订单--帮助菜单UI
     * @param isOP 是否手动操作 可以展开
     */
    private fun updateRentingMenu(isOP:Boolean = true){
        mViewModel.orderDataFiled.get()?.let {
            if (it.state == DataCode.STATE_RENTING) {
                if (isShowRentHelp){
                    setRentingLayout(2,it) //已展开帮助列表->隐藏
                } else {
                    if (isOP)
                        setRentingLayout(3,it) //未展开帮助列表->展示
                }
            }
        }
    }

    /***********************************订单部分********结束**************************/


    /*-----------------------------地图部分-----S-----------------------------*/

    private fun initLocationPermission() {
        requestPermission(getString(R.string.Location_Permission_Tip), Manifest.permission.ACCESS_FINE_LOCATION,
            granted = {
                LogUtil.i("---is-Location perms")
                isInitPermission = true
                setLocationUpdateListener()
            })
    }

    override fun onPermissionsGranted(requestCode: Int, perms: List<String>) {
        super.onPermissionsGranted(requestCode, perms)
        LogUtil.i("---Granted-Perms:$perms")
        isInitPermission = true
        setLocationUpdateListener()
    }

    /**提示打开定位开关*/
    private fun showLocationSwitchDialog(){
        if (versionDialog?.isShowing == true)
            return
        locationDialog?.dismiss()
        locationDialog = AppDialogUtil.instance.showLocationSwitchDialog(this) {
            val intent = Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
            startActivity(intent)
        }
    }

    private fun getMapLocation() {
        if (!Tool.isLocServiceEnable(this)){
            showLocationSwitchDialog()
            return
        }
        try {
            val locationTask: Task<Location> = fusedLocationClient.lastLocation
            locationTask.addOnCompleteListener { task: Task<Location?> ->
                if (task.isSuccessful && null != task.result) {
                    val latL = LatLng(task.result!!.latitude, task.result!!.longitude)
                    DataAppManager.instance.saveLocalLatLng(latL)
                    updateLocation(latL)
                } else {
                    val defaultLocation = DataAppManager.instance.getDefaultLatLng()
                    updateLocation(defaultLocation)
                }
            }
            locationTask.addOnFailureListener {
                val defaultLocation = DataAppManager.instance.getDefaultLatLng()
                updateLocation(defaultLocation)
            }
        } catch (e: SecurityException) {
            val defaultLocation = DataAppManager.instance.getDefaultLatLng()
            updateLocation(defaultLocation)
        }
    }

    /**原生定位获取方式*/
    private fun setLocationUpdateListener() {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            val defaultLocation = DataAppManager.instance.getDefaultLatLng()
            updateLocation(defaultLocation)
            return
        }
        isLocationReady = true
        if (!isMapReady) {
            setMapReady()
        }
        getMapLocation()
    }

    //设置地图样式+事件监听
    private fun setMapReady() {
        mMap?.let { map ->
            LogUtil.d("----setMapReady")
            try {
                map.isMyLocationEnabled = true
            } catch (e: SecurityException) {
                e.printStackTrace()
            }
            isMapReady = true
        }
    }

    private fun updateLocation(sydney: LatLng) {
        DataAppManager.instance.saveLocalLatLng(sydney)
        updateMapLayout(sydney)
    }

    /**刷新布局*/
    private fun updateMapLayout(sydney: LatLng) {
        if (mMap == null) {
            return
        }
        try {
            mMap?.moveCamera(CameraUpdateFactory.newLatLngZoom(sydney, zoomLevel))
        } catch (e: Exception) {
            // 忽略异常
        }
        //移动地图到中心
        mMap?.moveCamera(CameraUpdateFactory.newLatLngZoom(sydney, zoomLevel))
        // 保存位置
        DataAppManager.instance.saveLocalLatLng(sydney)
        // 更新上一次 zoom 级别（程序控制的移动应该触发查询）
        lastZoomLevel = zoomLevel
        // 注意：地图移动完成后会自动触发 onCameraIdle，由防抖机制统一处理查询
        android.util.Log.d("MainActivity", "地图移动到位置: lat=${sydney.latitude}, lng=${sydney.longitude}")
    }

    /**刷新网点数据*/
    private fun refreshCluster(list: List<Any>) {
        try {
            android.util.Log.d("MainActivity", "刷新网点数据: 大小=${list.size}")
            
            // 将Any转换为BranchInfo用于地图展示
            val branchDataList = list.mapNotNull { item ->
                when (item) {
                    is BranchInfo -> {
                        android.util.Log.d("MainActivity", "网点数据: id=${item.id}, name=${item.branchName}, lat=${item.lat}, lng=${item.lng}")
                        item
                    }
                    else -> {
                        android.util.Log.w("MainActivity", "未知数据类型: ${item.javaClass.name}")
                        null
                    }
                }
            }
            android.util.Log.d("MainActivity", "转换后的BranchInfo数量: ${branchDataList.size}")
            
            branchList.clear()
            branchList.addAll(branchDataList)
            selectBranch = null
            oldMarker = null

            if (null != mClusterManager) {
                // 先清除 ClusterManager 中的所有 items
                mClusterManager?.clearItems()
                // 立即调用 cluster() 确保地图上的 markers 被清除
                mClusterManager?.cluster()
                android.util.Log.d("MainActivity", "已清除之前的网点标记")
                
                if (branchDataList.isNotEmpty()) {
                    android.util.Log.d("MainActivity", "开始添加标记点到地图，数量=${branchDataList.size}")
                    // 添加新的网点数据
                    mClusterManager?.addItems(branchDataList)
                    android.util.Log.d("MainActivity", "标记点添加完成，开始聚合")
                    // 重新聚合显示新的标记点
                    mClusterManager?.cluster()
                    android.util.Log.d("MainActivity", "标记点聚合完成")
                } else {
                    // 当前范围内没有商家，显示提示
                    android.util.Log.d("MainActivity", "当前视图范围内没有商家")
                    toastShow(getString(R.string.map_no_merchants) ?: "当前范围内没有商家")
                }
            }
            
            // 移除自动重置地图位置的逻辑，允许用户自由缩放和移动地图
            // 之前的逻辑会在 zoom 级别超过默认值时自动跳转到设备位置，导致用户体验不佳
        } catch (e: Exception) {
            android.util.Log.e("MainActivity", "刷新网点数据失败", e)
            e.printStackTrace()
        }
    }
    
    /**
     * 地图相机移动完成后的处理（带防抖）
     */
    private fun onMapCameraIdle() {
        // 取消之前的防抖任务
        debounceRunnable?.let { mHandler.removeCallbacks(it) }
        
        // 创建新的防抖任务
        debounceRunnable = Runnable {
            // 获取当前地图中心点坐标（用户当前位置或地图中心）
            val centerLatLng = currentCameraPosition?.target
                ?: DataAppManager.instance.getLocalLatLng()
            
            android.util.Log.d("MainActivity", "地图移动完成，查询商家: lat=${centerLatLng.latitude}, lng=${centerLatLng.longitude}")
            // 调用接口查询当前视图范围内的商家
            mViewModel.getMapBranchList(centerLatLng.latitude, centerLatLng.longitude)
        }
        
        // 延迟执行，实现防抖
        mHandler.postDelayed(debounceRunnable!!, DEBOUNCE_DELAY)
    }

    /**
     * 展示大头针网点数据
     *
     * @param item 网点数据
     */
    private fun showMapMarker(item: BranchInfo){
        if (selectBranch?.id == item.id)
            return
        //处理旧选中大头针
        selectBranch?.let { oldBranch ->
            oldMarker?.setIcon(BitmapDescriptorFactory.fromResource(if (oldBranch.isBusiness) R.mipmap.mark_map_unselected_on else R.mipmap.mark_map_unselected_off))
        }
        //设置新大头针 图片选中,并标记为旧大头针
        mBranchRenderer?.getBranchMarker(item)?.let { mk ->
            mk.setIcon(BitmapDescriptorFactory.fromResource(if (item.isBusiness) R.mipmap.mark_map_selected_on else R.mipmap.mark_map_selected_off))
            oldMarker = mk
        }
        selectBranch = item
        //填充网点卡片布局
        val host = DataAppManager.instance.getConfig(ConfigKey.FILE_HOST)
        val logoUrl = host + item.logo
        val logoDF = R.mipmap.icon_default_logo
        if (StrUtil.isEmpty(item.logo)){
            mBinding.ivLogo.load(logoDF) {
                //transformations(RoundedCornersTransformation(topLeft = 5f, topRight = 5f,bottomLeft = 5f, bottomRight = 5f))
            }
        }else{
            mBinding.ivLogo.load(logoUrl) {
                placeholder(logoDF)
                error(logoDF)
            }
        }
        //设置地图距离（使用网点数据中的distance字段，单位km，保留1位小数）
        val distanceStr = String.format("%.1f km", item.distance)
        mBinding.tvInstant.text = distanceStr
        mBinding.ivMapGo.setThrottleListener {
            val addressTx :String = if (!StrUtil.isEmpty(item.addressMap)) item.addressMap?:"" else item.address
            if (!StrUtil.isEmpty(addressTx)){
                MapJumpUtil.jumpToGoogleMap(this, addressTx)
            }
        }
        mBinding.tvBranchName.text = item.branchName
        mBinding.tvBranchAddress.text = item.address
        mBinding.tvAvailableNum.text = item.rent.toString()
        mBinding.tvReturnNum.text = item.recovery.toString()

        val isOnline :Boolean = item.isBusiness
        mBinding.ivStatus.visibility = if (isOnline) View.INVISIBLE else View.VISIBLE
        mBinding.tvBranchName.setTextColor(getViewColor(this, if (isOnline) R.color.color_39404D else R.color.color_888888))
        mBinding.tvRentAvailable.visibility = if (isOnline) View.VISIBLE else View.GONE
        mBinding.tvAvailableNum.visibility = if (isOnline) View.VISIBLE else View.GONE
        mBinding.tvReturnAvailable.visibility = if (isOnline) View.VISIBLE else View.GONE
        mBinding.tvReturnNum.visibility = if (isOnline) View.VISIBLE else View.GONE
        mBinding.tvOutLine.visibility = if (isOnline) View.GONE else View.VISIBLE
//        mBinding.ivMapGo.setImageResource(if (isOnline) R.mipmap.icon_nav_open else R.mipmap.icon_nav_closed)
//        mBinding.tvOpenTime.text =""
    }

    /**关闭大头针展开*/
    private fun closeMapMarker(){
        selectBranch?.let { oldBr ->
            oldMarker?.setIcon(BitmapDescriptorFactory.fromResource(if (oldBr.isBusiness) R.mipmap.mark_map_unselected_on else R.mipmap.mark_map_unselected_off))
        }
        selectBranch = null
    }


    inner class BranchRenderer(context: Context, map: GoogleMap, clusterManager: BrsClusterManager<BranchInfo>) :
        DefaultClusterRenderer<BranchInfo>(context, map, clusterManager) {

        fun getBranchMarker(item : BranchInfo):Marker?{
            return getMarker(item)
        }

        override fun shouldRenderAsCluster(cluster: Cluster<BranchInfo>): Boolean {
            return cluster.size > 20
        }

        override fun onBeforeClusterItemRendered(item: BranchInfo, markerOptions: MarkerOptions) {
            super.onBeforeClusterItemRendered(item, markerOptions)
            val icon = if (item.isBusiness) R.mipmap.mark_map_unselected_on else R.mipmap.mark_map_unselected_off
            markerOptions.position(item.position).icon(BitmapDescriptorFactory.fromResource(icon))
        }

        override fun onClusterItemUpdated(item: BranchInfo, marker: Marker) {
            super.onClusterItemUpdated(item, marker)
            val icon = if (item.isBusiness) R.mipmap.mark_map_unselected_on else R.mipmap.mark_map_unselected_off
            marker.setIcon(BitmapDescriptorFactory.fromResource(icon))
        }

    }

    /*-----------------------------地图部分-----E-----------------------------*/

    override fun onDestroy() {
        super.onDestroy()
        EventBus.unregister(this.javaClass.simpleName)
    }

    private var exitTime: Long = 0

    override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            if (System.currentTimeMillis() - exitTime < 1000L) {
                finishAffinity(); // 结束这个应用的所有Activity
            } else {
                exitTime = System.currentTimeMillis();
            }
            return true
        }
        return super.onKeyDown(keyCode, event)
    }

    /**
     * 更新商户中心菜单的显示状态
     * 根据用户权限控制商户中心菜单的显示/隐藏
     */
    private fun updateMerchantMenuVisibility() {
        val hasPermission = DataAppManager.instance.hasMerchantPermission()
        
        // 控制商户中心菜单的显示/隐藏
        mBinding.ilMenu.menuMerchants.visibility = if (hasPermission) {
            View.VISIBLE
        } else {
            View.GONE
        }
        
        // 日志输出
        LogUtil.d("MerchantPermission", "商户权限检查结果: $hasPermission, 菜单显示状态: ${if (hasPermission) "显示" else "隐藏"}")
    }
}